#pragma once

#include <functional>
#include "PtrHash.hpp"
#include "PtrDeepEqual.hpp"
#include "EndAwareIterator.hpp"


namespace terms {
	namespace util {
		/**
		 * \brief Hash a pointer by calculating the hash value of its
		 * referenced object.
		 *
		 * Hashing nullptr returns 0;
		 *
		 * \tparam Object The type of the referenced object
		 * \tparam BaseHash the hash function to use for calculating the
		 * object hash.
		 **/
		template <typename Object, typename BaseHash=std::hash<Object>>
		class PtrHash {
		private:
			BaseHash _base_hash;

		public:
			std::size_t
			operator()(const Object *obj) const
			{
				if (obj == nullptr) {
					return 0;
				} else {	
					return _base_hash(*obj);
				}	
			}
		};
	}
}	
